﻿using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using SSCCMembership.Web;
using System.Data.SqlClient;
using System.Data;
namespace SSCCMembership.Web.Services.Admin
{
    [ErrorHandlerBehavior]
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class RefCodesService
    {

        [OperationContract]
        public CodeType[] GetCodeTypes()
        {
            using (var Q = SSCCDatabase.Query("SELECT * FROM SSCC_REF_CodeType"))
            {
                return Q.Select((R) => 
                    {
                        RefCode[] RCs = new RefCode[0];
                        using (var RefQ = SSCCDatabase.Query("SELECT * FROM SSCC_REF_ReferenceCode WHERE CodeType=@CT ORDER BY Weight",
                            new SqlParameter("@CT", SqlDbType.Int), R["ID"]))
                        {
                            RCs = RefQ.Select((RQ) => new RefCode((int)RQ["ID"], RQ["ShortName"].ToString(), RQ["Description"].ToString(), (int)RQ["Weight"], RQ["MetaData"].Nullable<byte[]>())).ToArray();
                        }
                        return new CodeType((int)R["ID"], R["Name"].ToString(), R["Description"].ToString(), 
                            R["MetaDataTitle"].ToString(), R["MetaDataType"].Nullable<int?>(), RCs);
                    }).ToArray();
            }
        }

        [OperationContract]
        public int AddRefCode(int CodeType, RefCode RC)
        {
            Params P = new Params()
            {
                {new SqlParameter("@CT", SqlDbType.Int), CodeType},
                {new SqlParameter("@SN", SqlDbType.VarChar), RC.ShortName},
                {new SqlParameter("@DS", SqlDbType.VarChar), RC.Description},
                {new SqlParameter("@WG", SqlDbType.Int), RC.Weight},
                {new SqlParameter("@MD", SqlDbType.VarBinary), RC.MetaData}
            };
            SSCCDatabase.ExecuteStatement("INSERT INTO SSCC_REF_ReferenceCode (CodeType, ShortName, Description, Weight, MetaData)" +
                "VALUES (@CT, @SN, @DS, @WG, @MD)", P);

            return SSCCDatabase.HighestID("SSCC_REF_ReferenceCode");
        }

        [OperationContract]
        public void UpdateRefCode(int RefCodeID, string Property, object value)
        {
            SqlParameter P = new SqlParameter();
            switch (Property)
            {
                case "Weight":
                    P = new SqlParameter("@value", SqlDbType.Int);
                    break;
                case "ShortName":
                case "Description":
                    P = new SqlParameter("@value", SqlDbType.VarChar);
                    break;
                case "MetaData":
                    P = new SqlParameter("@value", SqlDbType.VarBinary);
                    break;
                default:
                    return;
            }
            Params Para = new Params()
            {
                {P, value.ToDBNullable()},
                {new SqlParameter("@ID", SqlDbType.Int), RefCodeID}
            };
            SSCCDatabase.ExecuteStatement("UPDATE SSCC_REF_ReferenceCode SET " + Property + "=@value WHERE ID=@ID", Para);

            
            //var RefC = DataContext.SSCC_REF_ReferenceCode.Where((RC) => RC.ID == RefCodeID).First();
            //RefC.UpdateProperty(Property, value);
            //DataContext.SaveChanges();
        }

        //public CodeType SelectCodeType(SSCC_REF_CodeType CT)
        //{
        //    var RefCodes = CT.SSCC_REF_ReferenceCode.OrderBy((RC)=>RC.Weight).Select(SelectRefCode).ToArray();
        //    return new CodeType(CT.ID, CT.Name, CT.Description, CT.MetaDataTitle, CT.MetaDataType, RefCodes);
        //}
        //public RefCode SelectRefCode(SSCC_REF_ReferenceCode RC)
        //{
        //    return new RefCode(RC.ID, RC.ShortName, RC.Description, RC.Weight, RC.MetaData);
        //}

        
    }

    [DataContract]
    public class CodeType
    {
        public CodeType(int ID, string Name, string Description, string MetaDataTitle, int? MetaDataType, RefCode[] RefCodes)
        {
            this.ID = ID;
            this.Name = Name;
            this.Description = Description;
            this.MetaDataTitle = MetaDataTitle;
            this.MetaDataType = MetaDataType;
            this.RefCodes = RefCodes;
        }
        [DataMember]
        public int ID { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Description { get; set; }
        [DataMember]
        public string MetaDataTitle { get; set; }
        [DataMember]
        public int? MetaDataType { get; set; }
        [DataMember]
        public RefCode[] RefCodes { get; set; }
    }

    [DataContract]
    public class RefCode
    {
        public RefCode(int ID, string ShortName, string Description, int Weight, byte[] MetaData)
        {
            this.ID = ID;
            this.ShortName = ShortName;
            this.Description = Description;
            this.Weight = Weight;
            this.MetaData = MetaData;
        }
        [DataMember]
        public int ID { get; set; }
        [DataMember]
        public string ShortName { get; set; }
        [DataMember]
        public string Description { get; set; }
        [DataMember]
        public int Weight { get; set; }
        [DataMember]
        public byte[] MetaData { get; set; }
    }
}
